package vip.xiaonuo.issued.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import java.io.File;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.stereotype.Service;
import vip.xiaonuo.core.exception.ServiceException;
import vip.xiaonuo.facedoor.iservice.IFaceDoorDtoService;
import vip.xiaonuo.facedoor.modular.devicebase.entity.DeviceBase;
import vip.xiaonuo.facedoor.modular.devicebase.mapper.DeviceBaseMapper;
import vip.xiaonuo.facedoor.modular.deviceset.entity.DwDeviceSet;
import vip.xiaonuo.facedoor.modular.deviceset.param.DwDeviceSetParam;
import vip.xiaonuo.facedoor.modular.deviceset.service.DwDeviceSetService;
import vip.xiaonuo.facedoor.iservice.IDeviceSetService;
import vip.xiaonuo.facedoor.rule.HQRulesEngine;
import vip.xiaonuo.facedoor.rule.RuleConstant;

import javax.annotation.Resource;

import vip.xiaonuo.facedoor.vo.haiqing.*;
import vip.xiaonuo.facedoor.vo.haiqing.GetAndSetGeneralParamRequest.InfoDTO;

@Service(RuleConstant.HQ + RuleConstant.DEVICE_SET)
@Slf4j
public class HQDeviceSetServiceImpl implements IDeviceSetService {

    @Resource
    private DeviceBaseMapper deviceBaseMapper;

    @Resource
    private DwDeviceSetService dwDeviceSetService;

    @Override
    public void saveOrUpdate(DwDeviceSetParam dwDeviceSetParam) {
        DeviceBase deviceBase = deviceBaseMapper.selectById(dwDeviceSetParam.getDeviceBaseId());
        if (deviceBase == null) {
            throw new ServiceException(500, "设备不存在！");
        }
        String uri = IFaceDoorDtoService.getBaseParam(dwDeviceSetParam.getIp(), Integer.parseInt(dwDeviceSetParam.getCabinetPort()));
        String password = Optional.ofNullable(deviceBase.getDevicePassword()).orElse("admin");
        RequestHeader requestHeader = new RequestHeader().setUserName("admin").setPassWord(password);
        try {
            DwDeviceSet deviceSet = dwDeviceSetService.getOne(new LambdaQueryWrapper<DwDeviceSet>()
                .eq(DwDeviceSet::getDeviceBaseId, dwDeviceSetParam.getDeviceBaseId()));
            // 新增
            if (deviceSet == null) {
                addDeviceSet(dwDeviceSetParam, uri, requestHeader);
                // 下发订阅信息
                uploadSunscribe(dwDeviceSetParam, uri, requestHeader, dwDeviceSetParam.getDeviceId());
                // ip 端口修改
                deviceBase.setCabinetIp(dwDeviceSetParam.getIp());
                deviceBase.setCabinetPort(dwDeviceSetParam.getCabinetPort());
                deviceBaseMapper.updateById(deviceBase);
                // 基础参数修改
            } else if (ObjectUtil.equal(dwDeviceSetParam.getUpdateType(),2)){
                // 基础参数修改
                updateBaseParam(dwDeviceSetParam, uri, requestHeader, deviceSet);
                // 下发订阅信息
                uploadSunscribe(dwDeviceSetParam, uri, requestHeader, deviceSet.getDeviceId());
                dwDeviceSetService.edit(dwDeviceSetParam);
                deviceBaseMapper.updateById(deviceBase);
                // ip端口修改
            }else if (ObjectUtil.equal(dwDeviceSetParam.getUpdateType(),0)){
                // ip 端口修改
                deviceBase.setCabinetIp(dwDeviceSetParam.getIp());
                deviceBase.setCabinetPort(dwDeviceSetParam.getCabinetPort());
                // 修改完毕后获取基础参数
                GetAndSetGeneralParamRequest generalParam = HQRulesEngine.faceDoorDtoService.getGeneralParam(uri, requestHeader);
                if (generalParam != null && generalParam.getInfo() != null) {
                    log.info("获取设备基础参数成功！");
                    BeanUtil.copyProperties(generalParam.getInfo(), dwDeviceSetParam);
                    // 下发订阅参数
                    uploadSunscribe(dwDeviceSetParam, uri, requestHeader, deviceSet.getDeviceId());
                    dwDeviceSetParam.setIdCardThreshold(generalParam.getInfo().getIDCardThreshold());
                    dwDeviceSetParam.setDeviceId(generalParam.getDeviceID());
                } else {
                    throw new ServiceException(500, "获取设备基础参数失败！");
                }
                dwDeviceSetService.edit(dwDeviceSetParam);
                deviceBaseMapper.updateById(deviceBase);
            }
        } catch (Exception e) {
            throw new ServiceException(500, "发生异常！异常信息为：" + ExceptionUtils.getMessage(e));
        }
    }

    private void uploadSunscribe(DwDeviceSetParam dwDeviceSetParam, String uri, RequestHeader requestHeader,Integer deviceId) throws Exception {
        SetSubscribeRequest setSubscribeRequest = new SetSubscribeRequest();
        SetSubscribeRequest.InfoDTO info = new SetSubscribeRequest.InfoDTO();
        info.setDeviceID(deviceId);
        info.setSubscribeAddr("http://"+ dwDeviceSetParam.getSeverIp()+":"+ dwDeviceSetParam.getSeverPort());
        setSubscribeRequest.setInfo(info);
        BaseResponse baseResponse = HQRulesEngine.faceDoorDtoService.setSubscribe(uri, setSubscribeRequest, requestHeader);
        if (ObjectUtil.equal(baseResponse.getCode(), 200)) {
            log.info("订阅信息设置成功！");
        } else {
            throw new ServiceException(
                500,
                "订阅信息设置失败 失败信息： code:"
                    + baseResponse.getCode()
                    + " message:  "
                    + Optional.ofNullable(baseResponse.getInfo().getResult())
                    .orElse("")
                    + " "
                    + Optional.ofNullable(baseResponse.getInfo().getDetail())
                    .orElse(""));
        }
    }
//
//    private void soundParam(DwDeviceSet deviceSet,DwDeviceSetParam dwDeviceSetParam, String uri, RequestHeader requestHeader) throws Exception {
//        GetAndSetSoundRequest doorCondition = new GetAndSetSoundRequest();
//        GetAndSetSoundRequest.InfoDTO infoDTO= new GetAndSetSoundRequest.InfoDTO();
//        BeanUtil.copyProperties(deviceSet,infoDTO);
//        doorCondition.setInfo(infoDTO);
//        BaseResponse baseResponse = HQRulesEngine.faceDoorDtoService.setSound(uri, doorCondition, requestHeader);
//        if (ObjectUtil.equal(baseResponse.getCode(), 200)) {
//            log.info("音频参数设置成功！");
//            dwDeviceSetService.edit(dwDeviceSetParam);
//        } else {
//            throw new ServiceException(
//                500,
//                "音频参数设置失败 失败信息： code:"
//                    + baseResponse.getCode()
//                    + " message:  "
//                    + Optional.ofNullable(baseResponse.getInfo().getResult())
//                    .orElse("")
//                    + " "
//                    + Optional.ofNullable(baseResponse.getInfo().getDetail())
//                    .orElse(""));
//        }
//    }
//
//    private void openDoorParam(DwDeviceSetParam dwDeviceSetParam, String uri, RequestHeader requestHeader) throws Exception {
//        GetAndSetDoorCondition doorCondition = new GetAndSetDoorCondition();
//        GetAndSetDoorCondition.InfoDTO infoDTO= new GetAndSetDoorCondition.InfoDTO();
//        BeanUtil.copyProperties(dwDeviceSetParam,infoDTO);
//        doorCondition.setInfo(infoDTO);
//        BaseResponse baseResponse = HQRulesEngine.faceDoorDtoService.setDoorCondition(uri, doorCondition, requestHeader);
//        if (ObjectUtil.equal(baseResponse.getCode(), 200)) {
//            log.info("开门参数设置成功！");
//            dwDeviceSetService.edit(dwDeviceSetParam);
//        } else {
//            throw new ServiceException(
//                500,
//                "开门参数设置失败 失败信息： code:"
//                    + baseResponse.getCode()
//                    + " message:  "
//                    + Optional.ofNullable(baseResponse.getInfo().getResult())
//                    .orElse("")
//                    + " "
//                    + Optional.ofNullable(baseResponse.getInfo().getDetail())
//                    .orElse(""));
//        }
//    }

    private void addDeviceSet(DwDeviceSetParam dwDeviceSetParam, String uri, RequestHeader requestHeader) throws Exception {
        // 新增时获取基础参数
        GetAndSetGeneralParamRequest generalParam = HQRulesEngine.faceDoorDtoService.getGeneralParam(uri, requestHeader);
        if (generalParam != null && generalParam.getInfo() != null) {
            log.info("获取设备基础参数成功！");
            BeanUtil.copyProperties(generalParam.getInfo(), dwDeviceSetParam);
            dwDeviceSetParam.setIdCardThreshold(generalParam.getInfo().getIDCardThreshold());
            dwDeviceSetParam.setDeviceId(generalParam.getDeviceID());
            DwDeviceSet one = dwDeviceSetService.getOne(new LambdaQueryWrapper<DwDeviceSet>().eq(DwDeviceSet::getDeviceId, generalParam.getDeviceID()));
            if(one!=null){
                throw new ServiceException(500, "该设备已经存在 请检查！");
            }
        } else {
            throw new ServiceException(500, "获取设备基础参数失败！");
        }
        dwDeviceSetService.add(dwDeviceSetParam);
    }

    private void updateBaseParam(DwDeviceSetParam dwDeviceSetParam, String uri, RequestHeader requestHeader, DwDeviceSet deviceSet) throws Exception {
        GetAndSetGeneralParamRequest setGeneralParamRequest = new GetAndSetGeneralParamRequest();
        InfoDTO infoDTO = new InfoDTO();
        BeanUtil.copyProperties(dwDeviceSetParam, infoDTO);
        infoDTO.setIDCardThreshold(dwDeviceSetParam.getIdCardThreshold());
        setGeneralParamRequest.setDeviceID(deviceSet.getDeviceId());
        setGeneralParamRequest.setInfo(infoDTO);
        infoDTO.setIPAddr(dwDeviceSetParam.getIp());
        BaseResponse baseResponse =
                HQRulesEngine.faceDoorDtoService.setGeneralParam(uri, setGeneralParamRequest, requestHeader);
        if (ObjectUtil.equal(baseResponse.getCode(), 200)) {
            log.info("基础信息设置成功！");
            dwDeviceSetService.edit(dwDeviceSetParam);
        } else {
            throw new ServiceException(
                    500,
                    "基础信息设置失败 失败信息： code:"
                            + baseResponse.getCode()
                            + " message:  "
                            + Optional.ofNullable(baseResponse.getInfo().getResult())
                                    .orElse("")
                            + " "
                            + Optional.ofNullable(baseResponse.getInfo().getDetail())
                                    .orElse(""));
        }
    }

    @Override
    public void restart(String deviceId) {
        // 调用接口远程重启
        DeviceBase deviceBase = deviceBaseMapper.selectById(deviceId);
        if (deviceBase == null) {
            throw new ServiceException(500, "设备不存在！");
        }

        DwDeviceSet deviceSet = dwDeviceSetService.getOne(new LambdaQueryWrapper<DwDeviceSet>().eq(DwDeviceSet::getDeviceBaseId, deviceBase.getId()));
        if (deviceSet==null){
            throw new ServiceException(500,"设备尚未设置! ");
        }

        String uri = IFaceDoorDtoService.getBaseParam(deviceBase.getCabinetIp(), Integer.parseInt(deviceBase.getCabinetPort()));

        String password = Optional.ofNullable(deviceBase.getDevicePassword()).orElse("admin");

        RequestHeader requestHeader = new RequestHeader().setUserName("admin").setPassWord(password);

        RebootDeviceRequest.InfoDTO infoDTO = new RebootDeviceRequest.InfoDTO();
        infoDTO.setIsRebootDevice(1);
        infoDTO.setDeviceID(deviceSet.getDeviceId());

        RebootDeviceRequest rebootDeviceRequest = new RebootDeviceRequest();
        rebootDeviceRequest.setInfo(infoDTO);

        try {
            BaseResponse baseResponse = HQRulesEngine.faceDoorDtoService.rebootDevice(uri, rebootDeviceRequest, requestHeader);
            if (ObjectUtil.equal(baseResponse.getCode(), 200)) {
                log.info("设备重启成功！");
            } else {
                throw new ServiceException(
                    500,
                    "设备重启失败 失败信息： code:"
                        + baseResponse.getCode()
                        + " message:  "
                        + Optional.ofNullable(baseResponse.getInfo().getResult())
                        .orElse("")
                        + " "
                        + Optional.ofNullable(baseResponse.getInfo().getDetail())
                        .orElse(""));
            }
        }catch (Exception e) {
            throw new ServiceException(500, "发生异常！异常信息为：" + ExceptionUtils.getMessage(e));
        }
    }
}
